/**
 * File: AbstractMatchLoadProcessor.java
 * Created by: mhaimel
 * Created on: 22 Jul 2009
 * CVS:  $Id: AbstractMatchLoadProcessor.java,v 1.3 2009/10/09 15:10:12 mhaimel Exp $
 */
package uk.ac.ebi.curtain.processor.load.impl;

import java.io.File;
import java.io.Serializable;
import java.util.Arrays;

import uk.ac.ebi.curtain.processor.AbstractProcessor;
import uk.ac.ebi.curtain.service.IdentifierStore;
import uk.ac.ebi.curtain.utils.CurtainUncheckedException;
import uk.ac.ebi.curtain.utils.data.DataEntry;
import uk.ac.ebi.curtain.utils.data.FileType;
import uk.ac.ebi.curtain.utils.data.MetaData;
import uk.ac.ebi.curtain.utils.file.FileInfo;
import uk.ac.ebi.curtain.utils.match.MatchDetails;
import uk.ac.ebi.curtain.utils.match.MatchEntryMapper;
import uk.ac.ebi.curtain.utils.match.MatchParser;

/**
 * @author mhaimel
 * 
 */
public abstract class AbstractMatchLoadProcessor<I extends Serializable, O extends Serializable>
		extends AbstractProcessor<I, O> {

	private volatile IdentifierStore<String, Integer> ctgIdx;

	@Override
	public void process() {
		DataEntry<File> dataEntries = getDataEntries();
		if(!dataEntries.getMetaData().getFileType().isIn(FileType.getMapTypes())){
			throw new CurtainUncheckedException(
					"File not supported for loading: " + getInput()+ "!! Supported are: " + Arrays.toString(FileType.getMapTypes()));
		}
		loadFile(dataEntries);
	}

	protected abstract void init(FileInfo fi, Integer cat, Integer inslen);

	protected abstract DataEntry<File> getDataEntries();

	protected void loadFile(DataEntry<File> entry) {
		getLog().debug("Load Match file: " + entry);
		if (entry.getEntries().length != 1) {
			throw new IllegalArgumentException(
					"Mapping should be provided in one file! " + entry);
		}
		final File file = entry.getEntries()[0];
		final MetaData meta = entry.getMetaData();
		FileInfo fi = new FileInfo(file, meta.getFileType(), meta.getReadType());
		MatchParser mp = meta.getFileType().getMatchParser();
		Integer cat = getContext().getArguments().getCategory(fi);
		Integer inslen = getContext().getArguments().getInsertLength(fi);
		init(fi,cat,inslen);
		mp.parse(fi, new MatchEntryMapper(){
			@Override
			public void mapEntry(MatchDetails details) {
				storeParsedEntry(details, meta,file);
			}
		});
		
		getLog().debug("Finished loading MAQ file " + fi);
	}
	
	protected abstract void postStore();

	protected abstract void storeParsedEntry(MatchDetails details, MetaData meta, File file);

	protected IdentifierStore<String, Integer> getCtgIdx() {
		if (null == ctgIdx) {
			ctgIdx = getContext().getContigIndex();
		}
		return ctgIdx;
	}
}
